package cn.edu.swu.mhans.common.util;

import java.beans.PropertyDescriptor;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;

/**
 * 对象属性工具类
 *
 * @author ZhanJingbo
 * @version 1.0.0
 * Created on 2018/3/27
 */
public class FieldUtils {

    private static final String TRUE = "true";

    private static final String WRITE_METHOD_PREFIX = "set";
    private static final String READ_METHOD_PREFIX = "get";

    public static Object getFieldObject(String valueString, Class fieldClass) {
        if (String.class.equals(fieldClass)) {
            return valueString;
        }
        if (Boolean.class.equals(fieldClass)) {
            return TRUE.equals(valueString.toLowerCase());
        }
        if (Character.class.equals(fieldClass)) {
            return valueString.charAt(0);
        }
        try {
            Constructor constructor = fieldClass.getConstructor(String.class);
            return constructor.newInstance(valueString);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public static void setProperty(Object object, String propertyName, Object propertyValue) throws Exception {
        String writeMethodName = WRITE_METHOD_PREFIX + StringUtils.getUpperCaseStringForFirstChar(propertyName);
        String readMethodName = READ_METHOD_PREFIX + StringUtils.getUpperCaseStringForFirstChar(propertyName);

        PropertyDescriptor descriptor = new PropertyDescriptor(propertyName, object.getClass(), readMethodName, writeMethodName);
        Method writeMethod = descriptor.getWriteMethod();
        writeMethod.invoke(object, propertyValue);
    }

    public static void copyFileds(Object fromObject, Object toObject) {
        if (!fromObject.getClass().equals(toObject.getClass())) {
            return;
        }
        try {
            Field[] fields = fromObject.getClass().getDeclaredFields();
            for (Field field : fields) {
                if (Modifier.isFinal(field.getModifiers()) || Modifier.isStatic(field.getModifiers())) {
                    continue;
                }
                field.setAccessible(true);
                Object value = field.get(fromObject);
                if (value != null) {
                    field.set(toObject, value);
                }
            }
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }

    public static void convert(Object fromObject, Object toObject) {
        Field[] fields = fromObject.getClass().getDeclaredFields();
        for (Field field : fields) {
            try {
                String fieldName = field.getName();
                Field copyField = toObject.getClass().getDeclaredField(fieldName);
                if (!copyField.getType().equals(field.getType())) {
                    continue;
                }
                copyField.setAccessible(true);
                field.setAccessible(true);
                copyField.set(toObject, field.get(fromObject));
            } catch (NoSuchFieldException e) {
                continue;
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        }
    }
}
